
#include "Logger/LogLevel.h"


namespace logger {

#define LEVEL_TO_NAME(name) \
    case Level::name:       \
        return #name;

std::string convertLevelToName(Level in) {
    switch (in) {
        LEVEL_TO_NAME(DEBUG2)
        LEVEL_TO_NAME(DEBUG1)
        LEVEL_TO_NAME(DEBUG0)
        LEVEL_TO_NAME(INFO)
        LEVEL_TO_NAME(WARN)
        LEVEL_TO_NAME(ERROR)
        LEVEL_TO_NAME(CRITICAL)
        LEVEL_TO_NAME(NONE)
        LEVEL_TO_NAME(UNKNOWN)
    }
    return "UNKNOWN";
}

#define LEVEL_TO_CHAR(name, ch) \
    case Level::name:           \
        return ch;

char convertLevelToChar(Level in) {
    switch (in) {
        LEVEL_TO_CHAR(DEBUG2, '2')
        LEVEL_TO_CHAR(DEBUG1, '1')
        LEVEL_TO_CHAR(DEBUG0, '0')
        LEVEL_TO_CHAR(INFO, 'I')
        LEVEL_TO_CHAR(WARN, 'W')
        LEVEL_TO_CHAR(ERROR, 'E')
        LEVEL_TO_CHAR(CRITICAL, 'C')
        LEVEL_TO_CHAR(NONE, 'N')
        LEVEL_TO_CHAR(UNKNOWN, 'U')
    }
    return '?';
}

#define NAME_TO_LEVEL(name) \
    { #name, Level::name }

Level convertNameToLevel(const std::string& in) {
    static std::unordered_map<std::string, Level> nameToLevel = { NAME_TO_LEVEL(DEBUG2),
                                                                  NAME_TO_LEVEL(DEBUG1),
                                                                  NAME_TO_LEVEL(DEBUG0),
                                                                  NAME_TO_LEVEL(INFO),
                                                                  NAME_TO_LEVEL(WARN),
                                                                  NAME_TO_LEVEL(ERROR),
                                                                  NAME_TO_LEVEL(CRITICAL),
                                                                  NAME_TO_LEVEL(NONE),
                                                                  NAME_TO_LEVEL(UNKNOWN)};
    auto it = nameToLevel.find(in);
    if (it != nameToLevel.end()) {
        return it->second;
    }
    return Level::UNKNOWN;
}

}  // namespace logger
